﻿using HslCommunication.ModBus;
using Prism.Events;
using RoboAssembleX.Application.ActionJobs;
using RoboAssembleX.Application.Common;
using RoboAssembleX.Application.AddBoard1;
using RoboAssembleX.Application.AddGlass;
using RoboAssembleX.Application.AddGlass1;
using RoboAssembleX.Application.AddNeedle1;
using RoboAssembleX.Application.Robot;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RoboAssembleX.Application.AddBoard2;
using RoboAssembleX.Application.AddNeedle2;
using HslCommunication.MQTT;
using HslCommunication;
using RoboAssembleX.Application.Vision;

namespace RoboAssembleX.Application.ActionJbo
{
    public class AutoRunService
    {
        private readonly addGlass1Model addGlass1Model;
        private readonly AddGlass1Service addGlass1Service;
        private readonly RoboModel roboModel;
        private readonly RoboService roboService;
        private readonly AutoRunModel autoRunModel;
        private readonly IEventAggregator eventAggregator;
        private readonly AddBoard1Model addBoard1Model;
        private readonly AddBoard2Model addBoard2Model;
        private readonly AddBoard1Service addBoard1Service;
        private readonly AddBoard2Service addBoard2Service;
        private readonly AddNeedle2Model addNeedle2Model;
        private readonly AddNeedle2Service addNeedle2Service;
        private readonly AddNeedle1Model addNeedle1Model;
        private readonly AddNeedle1Service addNeedle1Service;
        private readonly VisionService visionService;
        private MqttClient mqttClient;
        public AutoRunService(addGlass1Model AddGlass1Model,AddGlass1Service AddGlass1Service, RoboModel roboModel, RoboService roboService,
            AutoRunModel autoRunModel, IEventAggregator eventAggregator,AddBoard1Model AddBoard1Model, AddBoard2Model AddBoard2Model, AddBoard1Service AddBoard1Service,
            AddBoard2Service AddBoard2Service, AddNeedle2Model AddNeedle2Model, AddNeedle2Service AddNeedle2Service,
            AddNeedle1Model AddNeedle1Model,AddNeedle1Service AddNeedle1Service, VisionService visionService)
        {
            this.addGlass1Model = AddGlass1Model;
            this.addGlass1Service = AddGlass1Service;
            this.roboModel = roboModel;
            this.roboService = roboService;
            this.autoRunModel = autoRunModel;
            this.eventAggregator = eventAggregator;
            this.addBoard1Model = AddBoard1Model;
            this.addBoard2Model = AddBoard2Model;
            this.addBoard1Service = AddBoard1Service;
            this.addBoard2Service = AddBoard2Service;
            this.addNeedle2Model = AddNeedle2Model;
            this.addNeedle2Service = AddNeedle2Service;
            this.addNeedle1Model = AddNeedle1Model;
            this.addNeedle1Service = AddNeedle1Service;
            this.visionService = visionService;
            LoadJobs();
        }

        public void SwitchAutoRun()
        {
            if (autoRunModel.AutoRunFlag)
            {
                if (mqttClient != null && mqttClient.IsConnected)
                    mqttClient.ConnectClose();
                autoRunModel.AutoRunFlag = false;
                eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs("自动运行停止!", 1));
            }
            else
            {
                if(!roboModel.RebotEnable)
                {
                    eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs("机械臂未使能!", 1));
                }
                else
                {
                    mqttClient = new MqttClient(new MqttConnectionOptions()
                    {
                        IpAddress="172.16.40.5",
                        Port=1883
                    });

                    OperateResult connect = mqttClient.ConnectServer();
                    if (!connect.IsSuccess)
                    {
                        eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs("连接数据发布服务器失败!", 1));
                        return;
                    }

                    autoRunModel.AutoRunFlag = true;
                    Task.Run(AutoRunTask1);
                    Task.Run(AutoRunTask2);
                    Task.Run(AutoRunTask3);
                    Task.Run(ProdQtyPublishTask);
                    eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs("自动运行启动!", 1));
                }
                
            }
        }

        async Task AutoRunTask1()
        {
            while(autoRunModel.AutoRunFlag)
            {
                
                if (roboModel.InPos && autoRunModel.ActionJbos.Where(m => m.Priority == 1).Count(m => m.Running) == 0)
                {
                    foreach (var job in autoRunModel.ActionJbos.Where(m=>m.Priority == 1))
                    {
                        if(job.IsReady)
                        {
                            eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"开始执行任务{job.Name}", 1));
                            await job.RunActionAsync();
                            eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"执行任务{job.Name}完成:,{autoRunModel.ProdQty}", 1));
                        }
                    }
                }
               await Task.Delay(500);
            }
        }
        async Task AutoRunTask2()
        {
            while (autoRunModel.AutoRunFlag)
            {

                if (autoRunModel.ActionJbos.Where(m => m.Priority == 2).Count(m => m.Running) == 0)
                {
                    foreach (var job in autoRunModel.ActionJbos.Where(m => m.Priority == 2))
                    {
                        if (job.IsReady)
                        {
                            eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"开始执行任务{job.Name}", 1));
                            await job.RunActionAsync();
                            eventAggregator.GetEvent<MessageEvent>().Publish(new MessageEventArgs($"执行任务{job.Name}完成", 1));
                        }
                    }
                }
                await Task.Delay(500);
            }
        }
        async Task AutoRunTask3()
        {
            while (autoRunModel.AutoRunFlag)
            {
                if (autoRunModel.EnableJobReadyFlag)
                {
                    var runjob = autoRunModel.ActionJbos.FirstOrDefault(m => m.Priority == 1 && m.Running);
                    if (runjob != null && autoRunModel.ActionJbos.Count(m => m.Priority == 1 && m.IsReady && m != runjob) > 0)
                    {
                        var redayjob = autoRunModel.ActionJbos.FirstOrDefault(m => m.Priority == 1 && m.IsReady && m.Name != runjob.Name);
                        if (redayjob != null)
                        {
                            autoRunModel.NextJobReadyFlag = true;
                            await roboService.NextJobStatusAsync(autoRunModel.NextJobReadyFlag);
                        }
                        else
                        {
                            autoRunModel.NextJobReadyFlag = false;
                            await roboService.NextJobStatusAsync(autoRunModel.NextJobReadyFlag);
                        }
                    }
                    else
                    {
                        autoRunModel.NextJobReadyFlag = false;
                        await roboService.NextJobStatusAsync(autoRunModel.NextJobReadyFlag);
                    }
                }
                await Task.Delay(500);
            }
        }
        async Task ProdQtyPublishTask()
        {
            while (autoRunModel.AutoRunFlag)
            {
                MqttApplicationMessage msg = new MqttApplicationMessage();
                msg.Topic = "封接/装配/自动装配线01/产量";
                msg.Payload = Encoding.UTF8.GetBytes(autoRunModel.ProdQty.ToString());
                await mqttClient.PublishMessageAsync(msg);
                await Task.Delay(1000 * 60);
            }
        }
        void LoadJobs()
        {
            autoRunModel.ActionJbos.Add(new ActionJob01(eventAggregator, roboModel, roboService, addGlass1Model, addGlass1Service, addBoard2Model) { Priority = 1});
            autoRunModel.ActionJbos.Add(new ActionJob02(eventAggregator,roboModel, roboService, addGlass1Model, addGlass1Service, addBoard2Model) { Priority = 1 });
            autoRunModel.ActionJbos.Add(new ActionJob03(eventAggregator, roboModel, roboService, addGlass1Model,addNeedle1Model,addNeedle1Service) { Priority = 1 });
            autoRunModel.ActionJbos.Add(new ActionJob04(eventAggregator, roboModel, roboService, addGlass1Model,addNeedle1Model,addNeedle1Service) { Priority = 1 });
            autoRunModel.ActionJbos.Add(new ActionJob05(eventAggregator, roboModel, roboService, addNeedle1Model, addNeedle2Model, addNeedle2Service) { Priority = 1 });
            autoRunModel.ActionJbos.Add(new ActionJob06(eventAggregator, roboModel, roboService, addNeedle2Model,autoRunModel) { Priority = 1});
            autoRunModel.ActionJbos.Add(new ActionJob07(eventAggregator, roboModel, roboService, addGlass1Model, addBoard2Model) { Priority = 1});
            autoRunModel.ActionJbos.Add(new ActionJob08(eventAggregator, roboModel, roboService, addNeedle1Model, addBoard2Model, addNeedle1Service) { Priority = 1});
            autoRunModel.ActionJbos.Add(new ActionJob51(eventAggregator, addBoard1Model, addBoard1Service, addBoard2Model) { Priority = 2 });
            autoRunModel.ActionJbos.Add(new ActionJob52(eventAggregator, addBoard2Service, addBoard2Model,visionService) { Priority = 2 });
        }
    }
}
